﻿using Bentley.DgnPlatformNET;
using Bentley.DgnPlatformNET.DgnEC;
using Bentley.DgnPlatformNET.Elements;
using Bentley.GeoCoordinates;
using Bentley.GeometryNET;
using Bentley.MstnPlatformNET;
using CheccCoverplateCulvertAssemble.Entity;
using CheccCoverplateCulvertAssemble.Tools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using CIMNETSolid = Bentley.CIMNET.CIMGeometry.Solid;
using CheccCoverplateCulvertAssemble.Rebar;
using CheccCoverplateCulvertAssemble.Conmmon;
using static Bentley.CIMNET.CIMGeometry.Solid.SolidUtil.Modify;
using Aspose.Cells;
using System.Data.Odbc;
using Bentley.CifNET.LinearGeometry;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using CheccTexturePropertyGive;
using static CheccTexturePropertyGive.SetCoverCulvertTexture;
using CheccCoverplateCulvertAssemble.Common;

namespace CheccCoverplateCulvertAssemble.Operation
{
    public class UnitaryBasicLeft : ConstructingEntity
    {
        RebarEntity rebarEntity;
        public UnitaryBasicLeft(BasicConstructor basicConstructor, RebarEntity rebarEntity, CulvertType culvertType, ConstructionMethod constructionMethod, CulvertComponentType culvertComponentType) : base(basicConstructor, culvertType, constructionMethod, culvertComponentType)
        {
            this.rebarEntity = rebarEntity;
        }

        public override void CreateEntityModel()
        {
            var objParameter = GetUorCoverParameter();
            DPoint3d[] points =
            {
                new DPoint3d(0,(objParameter.clearSpan / 2 + objParameter.standPly),0)* GeneralBank.UorToMeters,
                new DPoint3d(0,(objParameter.clearSpan / 2 + objParameter.standPly) ,-(objParameter.piecePly + objParameter.clearHeight)) * GeneralBank.UorToMeters,
                new DPoint3d(0,(objParameter.clearSpan / 2 + objParameter.standPly + objParameter.basicsEdge),-(objParameter.piecePly + objParameter.clearHeight))* GeneralBank.UorToMeters,
                new DPoint3d(0,(objParameter.clearSpan / 2 + objParameter.standPly + objParameter.basicsEdge),-(objParameter.piecePly + objParameter.clearHeight + objParameter.basicsPly)) * GeneralBank.UorToMeters,
                new DPoint3d(0,-(objParameter.clearSpan / 2 + objParameter.standPly + objParameter.basicsEdge),-(objParameter.piecePly + objParameter.clearHeight + objParameter.basicsPly)) * GeneralBank.UorToMeters,
                new DPoint3d(0,-(objParameter.clearSpan / 2 + objParameter.standPly + objParameter.basicsEdge),-(objParameter.piecePly + objParameter.clearHeight)) * GeneralBank.UorToMeters,
                new DPoint3d(0,-(objParameter.clearSpan / 2 + objParameter.standPly),-(objParameter.piecePly + objParameter.clearHeight)) * GeneralBank.UorToMeters,
                new DPoint3d(0,-(objParameter.clearSpan / 2 + objParameter.standPly),0) * GeneralBank.UorToMeters,

                new DPoint3d(0,-(objParameter.clearSpan / 2 + objParameter.standPly - objParameter.standTopWidth),0) * GeneralBank.UorToMeters,
                new DPoint3d(0, -(objParameter.clearSpan / 2 + objParameter.standPly - objParameter.standTopWidth),-objParameter.piecePly) * GeneralBank.UorToMeters,
                new DPoint3d(0, -(objParameter.clearSpan / 2) ,-objParameter.piecePly)* GeneralBank.UorToMeters,
                new DPoint3d(0, -(objParameter.clearSpan / 2),-(objParameter.piecePly + objParameter.clearHeight - objParameter.bottomChamfer))* GeneralBank.UorToMeters,
                new DPoint3d(0, -(objParameter.clearSpan / 2 - objParameter.bottomChamfer),-(objParameter.piecePly + objParameter.clearHeight)) * GeneralBank.UorToMeters,
                new DPoint3d(0, (objParameter.clearSpan / 2 - objParameter.bottomChamfer),-(objParameter.piecePly + objParameter.clearHeight)) * GeneralBank.UorToMeters,
                new DPoint3d(0,objParameter.clearSpan / 2,-(objParameter.piecePly + objParameter.clearHeight - objParameter.bottomChamfer)) * GeneralBank.UorToMeters,
                new DPoint3d(0, objParameter.clearSpan / 2 ,-objParameter.piecePly) * GeneralBank.UorToMeters,
                new DPoint3d(0, (objParameter.clearSpan / 2 + objParameter.standPly - objParameter.standTopWidth),-objParameter.piecePly )* GeneralBank.UorToMeters,
                new DPoint3d(0, (objParameter.clearSpan / 2 + objParameter.standPly - objParameter.standTopWidth),0) * GeneralBank.UorToMeters,
                new DPoint3d(0,(objParameter.clearSpan / 2 + objParameter.standPly),0) * GeneralBank.UorToMeters,
            };

            ShapeElement shapeElement = new ShapeElement(GeneralBank.ActiveDgnModel, null, points);
            CurveVector secCur = shapeElement.GetCurveVector();
            double LeftLateralOffset = Math.Abs((objParameter.standPly * 2 + objParameter.clearSpan + objParameter.basicsEdge * 2) * Math.Tan((90 - objParameter.leftLateralAngle) * Math.PI / 180));
            //涵长扣除城墙缝宽度
            double realLength = objParameter.culvertGapWidth / 2;
            LineElement lineElement = GetSlopLinee(DPoint3d.Zero, objParameter.basicsLength - realLength + LeftLateralOffset / 2, objParameter.baseSlope,out DPoint3d slopeEndPT);
            CurveVector linePath = lineElement.GetCurveVector();
            SolidKernelEntity solidKernel = CreateBodyFromSweep(linePath, secCur, GeneralBank.ActiveDgnModel);

            double z = LeftLateralOffset / 2 * objParameter.baseSlope;
            DPoint3d movePoint3d = new DPoint3d(-LeftLateralOffset / 2, 0, -z) * GeneralBank.UorToMeters;
            DTransform3d trans = DTransform3d.Identity;
            trans.Translation = movePoint3d;
            TransformBody(ref solidKernel, trans);
            if (objParameter.leftLateralAngle != 90)
            {
                LineElement cutLine = null;
                CurveVector cutLinePath = null;
            
                if (objParameter.leftLateralAngle <90)
                {
                    cutLine = new LineElement(GeneralBank.ActiveDgnModel, null, new DSegment3d(
                        new DPoint3d(-LeftLateralOffset / 2, -(objParameter.clearSpan / 2 + objParameter.standPly + objParameter.basicsEdge), 0) * GeneralBank.UorToMeters,
                        new DPoint3d(LeftLateralOffset / 2, (objParameter.clearSpan / 2 + objParameter.standPly + objParameter.basicsEdge), 0) * GeneralBank.UorToMeters));
                }
                else if (objParameter.leftLateralAngle > 90)
                {
                    cutLine = new LineElement(GeneralBank.ActiveDgnModel, null, new DSegment3d(
                        new DPoint3d(LeftLateralOffset / 2, -(objParameter.clearSpan / 2 + objParameter.standPly + objParameter.basicsEdge), 0) * GeneralBank.UorToMeters,
                        new DPoint3d(-LeftLateralOffset / 2, (objParameter.clearSpan / 2 + objParameter.standPly + objParameter.basicsEdge), 0) * GeneralBank.UorToMeters));
                }
                cutLinePath = cutLine.GetCurveVector();
                Bentley.CIMNET.CIMGeometry.Solid.SolidUtil.Modify.CutSolidsWithCurves(out SolidKernelEntity[] solidKernels, solidKernel, cutLinePath, SolidCutMethod.Split, SolidCutDirection.Both, SolidCutMode.Through, 0);
                solidKernel = solidKernels[0];
            }
            Convert1.BodyToElement(out Element cutResultElement, solidKernel, null, GeneralBank.ActiveDgnModel);
            //cutResultElement.AddToModel();

            //真实位置
            DTransform3d dTransform = new DTransform3d(this.dMatrix3D);
            dTransform.Translation = this.placeDpoint3d * GeneralBank.UorToMeters;
            TransformInfo dTransFormInfo = new TransformInfo(dTransform);
            cutResultElement.ApplyTransform(dTransFormInfo);
            cutResultElement.AddToModel();
            CommonData.Instance.ElementIds.Add(cutResultElement.ElementId.ToString());

            //属性赋予
            SetCoverCulvertECProperty setCoverCulvertECProperty = new SetCoverCulvertECProperty();
            setCoverCulvertECProperty.SetWallECProperty(
                new List<Element> { cutResultElement},
                objParameter.basicsLength.ToString(),
                (objParameter.piecePly + objParameter.clearHeight + objParameter.basicsPly).ToString(),
                objParameter.standTopWidth.ToString(),
                (objParameter.standPly * 2 + objParameter.clearSpan + objParameter.basicsEdge * 2).ToString(),
                objParameter.bottomChamfer.ToString(),
                "",
                ""
                );
            //材质赋予
            SetCoverCulvertTexture setCoverCulvertTexture = new SetCoverCulvertTexture();
            setCoverCulvertTexture.CoverCulvertTexture(cutResultElement, CoverCulvertConstruction.WallBody);

            //创建钢筋实体
            if (this.RebarList.Any())
            {
                foreach (var rebar in this.RebarList)
                {
                    Element rebarElement = rebar.CreateEntityModel();
                    rebarElement.ApplyTransform(dTransFormInfo);
                    rebarElement.AddToModel();
                    rebar.AddElmentMaterial(rebarElement);
                    CommonData.Instance.ElementIds.Add(rebarElement.ElementId.ToString());
                }
            }
        }

        /// <summary>
        /// 基于dPoint3D点沿X轴绘制线
        /// </summary>
        /// <param name="boxCulvertLength">涵长水平距离</param>
        /// <param name="slop">坡度; (例如0.1就是10%的坡率)</param>
        /// <returns></returns>
        public LineElement GetSlopLinee(DPoint3d dPoint3D, double boxCulvertLength, double slop,out DPoint3d endPt)
        {
            double z = boxCulvertLength * slop ;
            endPt = new DPoint3d(dPoint3D.X + boxCulvertLength, dPoint3D.Y, dPoint3D.Z + z) * GeneralBank.UorToMeters;
            return new LineElement(GeneralBank.ActiveDgnModel, null, new DSegment3d(dPoint3D * GeneralBank.UorToMeters , new DPoint3d(dPoint3D.X +boxCulvertLength, dPoint3D.Y, dPoint3D.Z +z) *GeneralBank.UorToMeters));
        }


        public override List<RebarBase> CreateRebarList()
        {
            List<RebarBase> rebarList = new();
            if(this.rebarEntity.dgv_Rebar1.Count == 0 ) return rebarList;   
            rebarList.AddRange(this.CreateRebarListNum1());
            rebarList.AddRange(this.CreateRebarListNum2());
            rebarList.AddRange(this.CreateRebarListNum2_1());
            rebarList.AddRange(this.CreateRebarListNum3());
            rebarList.AddRange(this.CreateRebarListNum4());
            rebarList.AddRange(this.CreateRebarListNum5());
            if (this.rebarEntity.dgv_Rebar6.Count > 0)
            {
                rebarList.AddRange(this.CreateRebarListNum6());
            }
            return rebarList;
        }

        /// <summary>
        /// 获取整体式洞身构造参数
        /// </summary>
        /// <returns> 涵长,左偏角,右偏角,涵身沉降缝宽度,基础沉降缝宽度,涵底坡度, 净跨,净高,挡块高度,基础襟边,台身厚度,台身顶宽,底部倒角,基础厚度,净保护层</returns>
        /// 
        private (double basicsLength, double leftLateralAngle, double rightLateralAngle, double culvertGapWidth, double baseGapWidth, double baseSlope, double clearSpan, double clearHeight,
            double piecePly, double basicsEdge, double standPly, double standTopWidth, double bottomChamfer, double basicsPly, double protectiveLayer) GetUorCoverParameter()
        {
            double basicsLength = this.basicConstructor.BasicsLength/ 100;
            double leftLateralAngle = this.basicConstructor.LeftLateralAngle;
            double rightLateralAngle = this.basicConstructor.RightLateralAngle;
            double culvertGapWidth = this.basicConstructor.CulvertGapWidth / 100;
            double baseGapWidth = this.basicConstructor.BaseGapWidth / 100;
            double baseSlope = this.basicConstructor.CulvertBaseSlope / 100;
            double clearSpan = this.basicConstructor.ClearSpan;
            double clearHeight = this.basicConstructor.ClearHeight;
            double piecePly = this.basicConstructor.PiecePly / 100;
            double basicsEdge = this.basicConstructor.BasicsEdge / 100;
            double standPly = this.basicConstructor.StandPly / 100;
            double standTopWidth = this.basicConstructor.StandTopWidth / 100;
            double bottomChamfer = this.basicConstructor.BottomChamfer / 100;
            double basicsPly = this.basicConstructor.BasicsPly / 100;
            double protectiveLayer = this.basicConstructor.ProtectiveLayer;
            return (basicsLength, leftLateralAngle, rightLateralAngle, culvertGapWidth, baseGapWidth, baseSlope, clearSpan, clearHeight, piecePly, basicsEdge, standPly, standTopWidth, bottomChamfer, basicsPly, protectiveLayer);
        }

        /// <summary>
        /// 获取1#钢筋集合
        /// </summary>
        /// <returns></returns>
        private List<RebarBase> CreateRebarListNum1()
        {
            List<RebarBase> rebarList = new();
            var objParameter = GetUorCoverParameter();
            var rebar1 = this.GetRebarParametersOfNum1();
            //涵身偏移长度
            double LeftLateralOffset = Math.Abs((objParameter.standPly * 2 + objParameter.clearSpan + objParameter.basicsEdge * 2) * Math.Tan((90 - objParameter.leftLateralAngle) * Math.PI / 180));
            //钢筋偏移长度
            double offsetLen = Math.Abs(objParameter.protectiveLayer / Math.Cos((90 - objParameter.leftLateralAngle) * Math.PI / 180));
            //摆放长度
            double putLength = objParameter.clearSpan + objParameter.standPly * 2 + objParameter.basicsEdge * 2 - rebar1.edgeDistance * 2;
            //摆放间距
            double putDistance = putLength / (rebar1.rebarRoot - 1);

            //距原点Z偏移长度
            double endZ = (objParameter.basicsLength - objParameter.culvertGapWidth / 2 - objParameter.protectiveLayer) * objParameter.baseSlope;

            LineElement cutLine = null;
            if (objParameter.leftLateralAngle < 90)
            {
                cutLine = new LineElement(GeneralBank.ActiveDgnModel, null, new DSegment3d(
                    new DPoint3d(-LeftLateralOffset / 2 + offsetLen, -(objParameter.clearSpan / 2 + objParameter.standPly + objParameter.basicsEdge), 0) * GeneralBank.UorToMeters,
                    new DPoint3d(LeftLateralOffset / 2 + offsetLen, (objParameter.clearSpan / 2 + objParameter.standPly + objParameter.basicsEdge), 0) * GeneralBank.UorToMeters));
            }
            else //if (objParameter.leftLateralAngle > 90)
            {
                cutLine = new LineElement(GeneralBank.ActiveDgnModel, null, new DSegment3d(
                    new DPoint3d(LeftLateralOffset / 2 + offsetLen, -(objParameter.clearSpan / 2 + objParameter.standPly + objParameter.basicsEdge), 0) * GeneralBank.UorToMeters,
                    new DPoint3d(-LeftLateralOffset / 2 + offsetLen, (objParameter.clearSpan / 2 + objParameter.standPly + objParameter.basicsEdge), 0) * GeneralBank.UorToMeters));
            }
            for (int i = 0; i < rebar1.rebarRoot; i++)
            {
                DPoint3d endPoint = new DPoint3d(objParameter.basicsLength - objParameter.culvertGapWidth / 2 - objParameter.protectiveLayer,
                    (objParameter.clearSpan / 2 + objParameter.standPly + objParameter.basicsEdge - rebar1.edgeDistance) - putDistance * i,
                    -(objParameter.piecePly + objParameter.clearHeight + objParameter.protectiveLayer + rebar1.diameter / 1000 / 2) + endZ);
                LineElement lineElement = new LineElement(GeneralBank.ActiveDgnModel, null, new DSegment3d(
                    new DPoint3d(-LeftLateralOffset, endPoint.Y, 0) * GeneralBank.UorToMeters,
                    endPoint * GeneralBank.UorToMeters));
                //if (objParameter.leftLateralAngle != 90)
                //{ 
                //LineElement lineElement = GetSlopLinee(new DPoint3d(staPoint.X, staPoint.Y - putDistance * i, staPoint.Z), rebar1Length, objParameter.baseSlope, out DPoint3d pt);
                CurveVector cveVcrInter1 = CurveVector.Create(CurveVector.BoundaryType.Inner);
                CurveVector cveVcrInter2 = CurveVector.Create(CurveVector.BoundaryType.Inner);
                CurveCurve.IntersectionsXY(cveVcrInter1, cveVcrInter2, cutLine.GetCurveVector(), lineElement.GetCurveVector());
                cveVcrInter1.GetStartPoint(out DPoint3d intersecPt);
                double staZ = intersecPt.X * objParameter.baseSlope;
                lineElement = new LineElement(GeneralBank.ActiveDgnModel, null, new DSegment3d(
                    new DPoint3d(intersecPt.X, intersecPt.Y, -(objParameter.piecePly + objParameter.clearHeight + objParameter.protectiveLayer + rebar1.diameter / 1000 / 2) * GeneralBank.UorToMeters + staZ),
                    endPoint * GeneralBank.UorToMeters));
                    //resultLine.AddToModel();
                    //Element ele = DraftingElementSchema.ToElement(GeneralBank.ActiveDgnModel, cveVcrInter1, null);
                //}
                RebarBase rebarBase1 = new RebarNoHook(this, "1", rebar1.diameter, rebar1.rebarGrade, RebarType.NoRibbed, lineElement.GetCurveVector());
                rebarList.Add(rebarBase1);
            }
            return rebarList;
        }


        /// <summary>
        /// 获取2#钢筋集合
        /// </summary>
        /// <returns></returns>
        private List<RebarBase> CreateRebarListNum2()
        {
            List<RebarBase> rebarList = new();
            double rebar6_diameter = 0;
            if (this.rebarEntity.dgv_Rebar6.Count > 0)
            {
                rebar6_diameter = Convert.ToDouble(this.rebarEntity.dgv_Rebar6[3]);
            }
            var objParameter = GetUorCoverParameter();
            var rebar1 = this.GetRebarParametersOfNum1();
            var rebar2 = this.GetRebarParametersOfNum2();

            //钢筋端点相对于原点偏移长度
            double LeftLateralOffset = Math.Abs((objParameter.standPly + objParameter.clearSpan / 2 + objParameter.basicsEdge - objParameter.protectiveLayer - rebar2.diameter / 1000 / 2) * Math.Tan((90 - objParameter.leftLateralAngle) * Math.PI / 180));
            //钢筋距净保护层水平距离
            double horizontalLen = Math.Abs(objParameter.protectiveLayer / Math.Cos((90 - objParameter.leftLateralAngle) * Math.PI / 180));
            //摆放长度
            double putLength = objParameter.basicsLength - objParameter.culvertGapWidth / 2 - objParameter.protectiveLayer - rebar2.diameter / 1000 / 2 - LeftLateralOffset  - horizontalLen; 
            //摆放间距
            double putDistance = 1.0 / (rebar2.rebarRoot - 1);
            //摆放根数
            int root = (int)Math.Floor(putLength / putDistance) + 1;

            double staX = objParameter.basicsLength - objParameter.culvertGapWidth / 2 - objParameter.protectiveLayer - rebar2.diameter / 1000 / 2;
            double staY = objParameter.clearSpan / 2 + objParameter.standPly + objParameter.basicsEdge - objParameter.protectiveLayer - rebar2.diameter / 1000 / 2;
            double staZ = objParameter.piecePly + objParameter.clearHeight + objParameter.protectiveLayer + rebar1.diameter / 1000 + rebar6_diameter / 1000 + rebar2.diameter / 1000 / 2;
            for (int i = 0; i < root; i++)
            {   //距原点Z偏移长度
                double offsetZ = (staX - putDistance * i) * objParameter.baseSlope;
                List<DPoint3d> points = new List<DPoint3d>();
                //points.Add(new DPoint3d(staX - putDistance * i, staY, -(staZ + rebar2.hookLength + -offsetZ)) * GeneralBank.UorToMeters);
                points.Add(new DPoint3d(staX - putDistance * i, staY, -(staZ + -offsetZ)) * GeneralBank.UorToMeters);
                points.Add(new DPoint3d(staX - putDistance * i, -staY, -(staZ + -offsetZ)) * GeneralBank.UorToMeters);
                //points.Add(new DPoint3d(staX - putDistance * i, -staY, -(staZ + rebar2.hookLength + -offsetZ)) * GeneralBank.UorToMeters);
                LineStringElement lineStringElement = new LineStringElement(GeneralBank.ActiveDgnModel, null, points.ToArray());
                RebarBase rebarBase2 = new Rebar_90Degrees(this, "2", rebar2.diameter, rebar2.rebarGrade, RebarType.NoRibbed, lineStringElement.GetCurveVector(), rebar2.hookLength, rebar2.diameter * 5 ,90, 90);
                //RebarBase rebarBase2 = new RebarNoHook(this, "2", rebar2.diameter, rebar2.rebarGrade, RebarType.NoRibbed, lineStringElement.GetCurveVector());
                rebarList.Add(rebarBase2);
            }
            return rebarList;
        }

        /// <summary>
        /// 获取2'#钢筋集合
        /// </summary>
        /// <returns></returns>
        private List<RebarBase> CreateRebarListNum2_1()
        {
            var objParameter = GetUorCoverParameter();
            List<RebarBase> rebarList = new();
            if (objParameter.leftLateralAngle == 90) return rebarList;
            double rebar6_diameter = 0;
            if (this.rebarEntity.dgv_Rebar6.Count > 0)
            {
                rebar6_diameter = Convert.ToDouble(this.rebarEntity.dgv_Rebar6[3]);
            }
            var rebar1 = this.GetRebarParametersOfNum1();
            var rebar2_1 = this.GetRebarParametersOfNum2_1();
            //涵身偏移长度
            double LeftLateralOffset = Math.Abs((objParameter.standPly * 2 + objParameter.clearSpan + objParameter.basicsEdge * 2) * Math.Tan((90 - objParameter.leftLateralAngle) * Math.PI / 180));
            //钢筋端点相对于原点偏移长度
            double rebarOffset = Math.Abs((objParameter.standPly + objParameter.clearSpan / 2 + objParameter.basicsEdge - objParameter.protectiveLayer  - rebar2_1.diameter / 1000 /2) * Math.Tan((90 - objParameter.leftLateralAngle) * Math.PI / 180));
            //钢筋距净保护层水平距离
            double horizontalLen = Math.Abs((objParameter.protectiveLayer + rebar2_1.diameter / 1000 / 2) / Math.Cos((90 - objParameter.leftLateralAngle) * Math.PI / 180));
            //摆放长度
            double putLength = LeftLateralOffset - horizontalLen;
            //摆放间距
            double putDistance = putLength / (rebar2_1.rebarRoot - 1);
            //摆放根数
            int root = rebar2_1.rebarRoot;
            double staY = objParameter.standPly + objParameter.clearSpan / 2 + objParameter.basicsEdge - objParameter.protectiveLayer - rebar2_1.diameter / 1000 / 2;
            double staZ = objParameter.piecePly + objParameter.clearHeight + objParameter.protectiveLayer + rebar1.diameter / 1000 + rebar6_diameter / 1000 + rebar2_1.diameter / 1000 / 2;
            for (int i = 0; i < root; i++)
            {
                //距原点Z偏移长度
                double staOffsetZ = (-rebarOffset + horizontalLen +  putDistance * i) * objParameter.baseSlope;
                double endOffsetZ = (rebarOffset + horizontalLen + putDistance * i) * objParameter.baseSlope;
                List<DPoint3d> points = new List<DPoint3d>();
                if (objParameter.leftLateralAngle < 90)
                {
                    //points.Add(new DPoint3d(rebarOffset + horizontalLen + putDistance * i, staY, -(rebar2_1.hookLength + staZ) + endOffsetZ) * GeneralBank.UorToMeters);
                    points.Add(new DPoint3d(rebarOffset + horizontalLen + putDistance * i, staY, -staZ + endOffsetZ) * GeneralBank.UorToMeters);
                    points.Add(new DPoint3d(-rebarOffset + horizontalLen + putDistance * i, -staY, -staZ + staOffsetZ) * GeneralBank.UorToMeters);
                    //points.Add(new DPoint3d(-rebarOffset + horizontalLen + putDistance * i, -staY, -(rebar2_1.hookLength + staZ) + staOffsetZ) * GeneralBank.UorToMeters);
                }
                else if (objParameter.leftLateralAngle > 90)
                {
                    //points.Add(new DPoint3d(-rebarOffset + horizontalLen + putDistance * i, staY, -(rebar2_1.hookLength + staZ) + staOffsetZ) * GeneralBank.UorToMeters);
                    points.Add(new DPoint3d(-rebarOffset + horizontalLen + putDistance * i, staY, -staZ + staOffsetZ) * GeneralBank.UorToMeters);
                    points.Add(new DPoint3d(rebarOffset + horizontalLen + putDistance * i, -staY, -staZ + endOffsetZ) * GeneralBank.UorToMeters);
                    //points.Add(new DPoint3d(rebarOffset + horizontalLen + putDistance * i, -staY, -(rebar2_1.hookLength + staZ) + endOffsetZ) * GeneralBank.UorToMeters);
                }
                if (points.Count > 0)
                {
                    LineStringElement lineStringElement = new LineStringElement(GeneralBank.ActiveDgnModel, null, points.ToArray());
                    RebarBase rebarBase2_1 = new Rebar_90Degrees(this, "2'", rebar2_1.diameter, rebar2_1.rebarGrade, RebarType.NoRibbed, lineStringElement.GetCurveVector(), rebar2_1.hookLength, rebar2_1.diameter * 5, 90, 90);
                    //RebarBase rebarBase2 = new RebarNoHook(this, "2'", rebar2_1.diameter, rebar2_1.rebarGrade, RebarType.NoRibbed, lineStringElement.GetCurveVector());
                    rebarList.Add(rebarBase2_1);
                }
            }

            return rebarList;
        }

        /// <summary>
        /// 获取3#钢筋集合
        /// </summary>
        /// <returns></returns>
        private List<RebarBase> CreateRebarListNum3()
        {
            //横纵都采用净保护层
            List<RebarBase> rebarList = new();
            var objParameter = GetUorCoverParameter();
            var rebar2 = this.GetRebarParametersOfNum2();
            var rebar3 = this.GetRebarParametersOfNum3();

            double staY = objParameter.clearSpan / 2 + objParameter.standPly - objParameter.protectiveLayer - rebar3.diameter / 1000 / 2;
            double staZ = objParameter.piecePly + objParameter.clearHeight + rebar3.rebarPlaceDepth;
            //钢筋端点相对于原点偏移长度
            double rebarOffset = Math.Abs(staY * Math.Tan((90 - objParameter.leftLateralAngle) * Math.PI / 180));
            //钢筋距净保护层水平距离
            double horizontalLen = Math.Abs((objParameter.protectiveLayer) / Math.Cos((90 - objParameter.leftLateralAngle) * Math.PI / 180));
            //摆放间距
            double putDistance = 1.0 / (int)(rebar3.rebarRoot / 2 - 1);
            //从右至左布置钢筋
            double staX = objParameter.basicsLength - objParameter.culvertGapWidth / 2 - objParameter.protectiveLayer - rebar2.diameter / 1000 - rebar3.diameter / 1000 / 2;
            //摆放长度
            double putLength = objParameter.leftLateralAngle > 90 ? staX  + rebarOffset - horizontalLen : staX - rebarOffset - horizontalLen;
            int num = (int)Math.Floor(putLength / putDistance) + 1;
            for (int i = 0; i < num; i++)
            {
                double offsetZ = (staX - putDistance * i) * objParameter.baseSlope;
                LineElement lineElement = new LineElement(GeneralBank.ActiveDgnModel, null,
                    new DSegment3d(new DPoint3d(staX - putDistance * i, staY, -staZ + offsetZ) * GeneralBank.UorToMeters,
                                    new DPoint3d(staX - putDistance * i, staY, -staZ + offsetZ + rebar3.rebarLength) * GeneralBank.UorToMeters));
                RebarBase rebarBase3 = new RebarNoHook(this, "3", rebar3.diameter, rebar3.rebarGrade, RebarType.NoRibbed, lineElement.GetCurveVector());
                rebarList.Add(rebarBase3);
            }
            putLength = objParameter.leftLateralAngle > 90 ? staX - rebarOffset - horizontalLen : staX + rebarOffset - horizontalLen;
            num = (int)Math.Floor(putLength / putDistance) + 1;
            for (int i = 0; i < num; i++)
            {
                double offsetZ = (staX - putDistance * i) * objParameter.baseSlope;
                LineElement lineElement = new LineElement(GeneralBank.ActiveDgnModel, null,
                    new DSegment3d(new DPoint3d(staX - putDistance * i, -staY, -staZ + offsetZ) * GeneralBank.UorToMeters,
                                    new DPoint3d(staX - putDistance * i, -staY, -staZ + offsetZ + rebar3.rebarLength) * GeneralBank.UorToMeters));
                RebarBase rebarBase3 = new RebarNoHook(this, "3", rebar3.diameter, rebar3.rebarGrade, RebarType.NoRibbed, lineElement.GetCurveVector());
                rebarList.Add(rebarBase3);
            }
            return rebarList;
        }
        /// <summary>
        /// 获取4#钢筋集合
        /// </summary>
        /// <returns></returns>
        private List<RebarBase> CreateRebarListNum4()
        {
            /*****四号钢筋布置方式*****
             * 纵向间距：从中间往外布置，剩余长度大于0.5m补充一根
             * 横向间距：从中间往外布置，剩余长度大于0.5m补充一根
             */
            List<RebarBase> rebarList = new();
            double rebar6_diameter = 0;
            if (this.rebarEntity.dgv_Rebar6.Count > 0)
            {
                rebar6_diameter = Convert.ToDouble(this.rebarEntity.dgv_Rebar6[3]);
            }
            var objParameter = GetUorCoverParameter();
            var rebar1 = this.GetRebarParametersOfNum1();
            var rebar2 = this.GetRebarParametersOfNum2();
            var rebar4 = this.GetRebarParametersOfNum4();

            Angle angle = Angle.FromDegrees(90 - objParameter.leftLateralAngle);
            //涵身偏移长度
            double LeftLateralOffset = Math.Abs((objParameter.standPly + objParameter.clearSpan /2 + objParameter.basicsEdge) * Math.Tan((90 - objParameter.leftLateralAngle) * Math.PI / 180));

            //钢筋长度
            double rebarLength = objParameter.basicsPly - (objParameter.protectiveLayer * 2 + rebar1.diameter / 1000 + rebar6_diameter / 1000 + rebar2.diameter / 1000 + rebar4.diameter / 1000);
            //单侧摆放长度Y轴
            double putLengthY = objParameter.clearSpan / 2 + objParameter.standPly + objParameter.basicsEdge - objParameter.protectiveLayer - rebar2.diameter / 1000 - rebar4.diameter / 1000 / 2 - rebar4.distanceY / 2;
            //单侧摆放根数Y轴
            int numY = (int)Math.Floor(putLengthY / rebar4.distanceY) + 1;
            if (putLengthY - rebar4.distanceY * (numY - 1) > 0.5) numY += 1;



            //单侧摆放长度X轴
            double putLengthX = (objParameter.basicsLength - objParameter.culvertGapWidth / 2 - LeftLateralOffset)/2  - 
                (objParameter.protectiveLayer + rebar2.diameter / 1000 + rebar4.diameter / 1000 / 2 + rebar4.distanceX / 2);
            //摆放根数
            int numX = (int)Math.Floor(putLengthX / rebar4.distanceX) + 1;
            if (putLengthX - rebar4.distanceX * (numX - 1) > 0.5) numX += 1;

            double staX = LeftLateralOffset + (objParameter.basicsLength - objParameter.culvertGapWidth / 2 - LeftLateralOffset) / 2  + rebar4.distanceX / 2;
            double staY = rebar4.distanceY / 2;
            double staZ = objParameter.piecePly + objParameter.clearHeight + objParameter.protectiveLayer + 
                rebar1.diameter / 1000 + rebar6_diameter / 1000 + rebar2.diameter / 1000 + rebar4.diameter / 1000 / 2;
            //平面右侧
            for (int j = 0; j < numX; j++)
            {
                double ptX = j == numX - 1 ? staX + putLengthX : staX + rebar4.distanceX * j;
                double offsetZ = ptX * objParameter.baseSlope;
                for (int i = 0; i < numY; i++)
                {
                    double ptY = i == numY - 1 ? staY + putLengthY : staY + rebar4.distanceY * i;
                    List<DPoint3d> points = new List<DPoint3d>();
                    //points.Add(new DPoint3d(ptX, ptY - rebar4.hookLength, -staZ + offsetZ) * GeneralBank.UorToMeters);
                    points.Add(new DPoint3d(ptX, ptY, -staZ + offsetZ) * GeneralBank.UorToMeters);
                    points.Add(new DPoint3d(ptX, ptY, -(staZ + rebarLength) + offsetZ) * GeneralBank.UorToMeters);
                    //points.Add(new DPoint3d(ptX, ptY - rebar4.hookLength, -(staZ + rebarLength) + offsetZ) * GeneralBank.UorToMeters);
                    LineStringElement lineStringElement = new LineStringElement(GeneralBank.ActiveDgnModel, null, points.ToArray());
                    RebarBase rebarBase4 = new Rebar_90Degrees(this, "4", rebar4.diameter, rebar4.rebarGrade, RebarType.NoRibbed, lineStringElement.GetCurveVector(), rebar4.hookLength, rebar4.diameter * 5, -90, -90);
                    //RebarBase rebarBase4 = new RebarNoHook(this, "4", rebar4.diameter, rebar4.rebarGrade, RebarType.NoRibbed, lineStringElement.GetCurveVector());
                    rebarList.Add(rebarBase4);
                }
                for (int i = 0; i < numY; i++)
                {
                    double ptY = i == numY - 1 ? -staY - putLengthY : -staY - rebar4.distanceY * i;
                    List<DPoint3d> points = new List<DPoint3d>();
                    //points.Add(new DPoint3d(ptX, ptY + rebar4.hookLength, -staZ + offsetZ) * GeneralBank.UorToMeters);
                    points.Add(new DPoint3d(ptX, ptY, -staZ + offsetZ) * GeneralBank.UorToMeters);
                    points.Add(new DPoint3d(ptX, ptY, -(staZ + rebarLength) + offsetZ) * GeneralBank.UorToMeters);
                    //points.Add(new DPoint3d(ptX, ptY + rebar4.hookLength, -(staZ + rebarLength) + offsetZ) * GeneralBank.UorToMeters);
                    LineStringElement lineStringElement = new LineStringElement(GeneralBank.ActiveDgnModel, null, points.ToArray());
                    RebarBase rebarBase4 = new Rebar_90Degrees(this, "4", rebar4.diameter, rebar4.rebarGrade, RebarType.NoRibbed, lineStringElement.GetCurveVector(), rebar4.hookLength, rebar4.diameter * 5, 90, 90);
                    //RebarBase rebarBase4 = new RebarNoHook(this, "4", rebar4.diameter, rebar4.rebarGrade, RebarType.NoRibbed, lineStringElement.GetCurveVector());
                    rebarList.Add(rebarBase4);
                }
            }

            //钢筋距净保护层水平距离
            double horizontalLen = Math.Abs((objParameter.protectiveLayer + rebar2.diameter / 1000 + rebar4.diameter / 1000 / 2) 
                / Math.Cos((90 - objParameter.leftLateralAngle) * Math.PI / 180));
            staX = LeftLateralOffset + (objParameter.basicsLength - objParameter.culvertGapWidth / 2 - LeftLateralOffset) / 2 - rebar4.distanceX / 2;
            //平面上左侧
            for (int i = 0; i < numY; i++)
            {
                double ptY = i == numY - 1 ? staY + putLengthY : staY + rebar4.distanceY * i;
                //钢筋端点相对于原点偏移长度
                double rebarOffset = Math.Abs(ptY * Math.Tan((90 - objParameter.leftLateralAngle) * Math.PI / 180));
                //单侧摆放长度X轴
                if (objParameter.leftLateralAngle > 90)
                {
                    putLengthX = Math.Abs(staX + rebarOffset - horizontalLen);
                }
                else //if (objParameter.leftLateralAngle < 90)
                {
                    putLengthX = staX - (rebarOffset + horizontalLen);
                }
                //摆放根数
                numX = (int)Math.Floor(putLengthX / rebar4.distanceX) + 1;
                if (putLengthX - rebar4.distanceX * (numX - 1) > 0.5) numX += 1;
                for (int j = 0; j < numX; j++)
                {
                    double ptX = j == numX - 1 ? staX - putLengthX : staX - rebar4.distanceX * j;
                    double offsetZ = ptX * objParameter.baseSlope;
                    List<DPoint3d> points = new List<DPoint3d>();
                    //points.Add(new DPoint3d(ptX, ptY - rebar4.hookLength, -staZ + offsetZ) * GeneralBank.UorToMeters);
                    points.Add(new DPoint3d(ptX, ptY, -staZ + offsetZ) * GeneralBank.UorToMeters);
                    points.Add(new DPoint3d(ptX, ptY, -(staZ + rebarLength) + offsetZ) * GeneralBank.UorToMeters);
                    //points.Add(new DPoint3d(ptX, ptY - rebar4.hookLength, -(staZ + rebarLength) + offsetZ) * GeneralBank.UorToMeters);
                    LineStringElement lineStringElement = new LineStringElement(GeneralBank.ActiveDgnModel, null, points.ToArray());

                    RebarBase rebarBase4 = null;
                    if (j != numX - 1)
                    {
                        rebarBase4 = new Rebar_90Degrees(this, "4", rebar4.diameter, rebar4.rebarGrade, RebarType.NoRibbed, lineStringElement.GetCurveVector(), rebar4.hookLength, rebar4.diameter * 5, -90, -90);
                    }
                    else
                    {
                        rebarBase4 = new Rebar_90Degrees(this, "4", rebar4.diameter, rebar4.rebarGrade, RebarType.NoRibbed, lineStringElement.GetCurveVector(), rebar4.hookLength, rebar4.diameter * 5, -90 + angle.Degrees, -90 + angle.Degrees);
                    }
                    
                    //if (j == numX - 1)
                    //{
                    //    DTransform3d dTransform3D = DTransform3d.FromRotationAroundLine(points[1], new DVector3d(0, 0, 1), -angle);
                    //    TransformInfo transInfo1 = new TransformInfo(dTransform3D);
                    //}
                    //RebarBase rebarBase4 = new RebarNoHook(this, "4", rebar4.diameter, rebar4.rebarGrade, RebarType.NoRibbed, lineStringElement.GetCurveVector());
                    rebarList.Add(rebarBase4);
                }
            }

            //平面下左侧
            for (int i = 0; i < numY; i++)
            {
                double ptY = i == numY - 1 ? -staY - putLengthY : -staY - rebar4.distanceY * i;
                //钢筋端点相对于原点偏移长度
                double rebarOffset = Math.Abs(ptY * Math.Tan((90 - objParameter.leftLateralAngle) * Math.PI / 180));
                //单侧摆放长度X轴
                if (objParameter.leftLateralAngle > 90)
                {
                    putLengthX = staX - (rebarOffset + horizontalLen);
                }
                else //if (objParameter.leftLateralAngle < 90)
                {
                    putLengthX = Math.Abs(staX + rebarOffset - horizontalLen);
                }
                //摆放根数
                numX = (int)Math.Floor(putLengthX / rebar4.distanceX) + 1;
                if (putLengthX - rebar4.distanceX * (numX - 1) > 0.5) numX += 1;
                for (int j = 0; j < numX; j++)
                {
                    double ptX = j == numX - 1 ? staX - putLengthX : staX - rebar4.distanceX * j;
                    double offsetZ = ptX * objParameter.baseSlope;

                    List<DPoint3d> points = new List<DPoint3d>();
                    //points.Add(new DPoint3d(ptX, ptY + rebar4.hookLength, -staZ + offsetZ) * GeneralBank.UorToMeters);
                    points.Add(new DPoint3d(ptX, ptY, -staZ + offsetZ) * GeneralBank.UorToMeters);
                    points.Add(new DPoint3d(ptX, ptY, -(staZ + rebarLength) + offsetZ) * GeneralBank.UorToMeters);
                    //points.Add(new DPoint3d(ptX, ptY + rebar4.hookLength, -(staZ + rebarLength) + offsetZ) * GeneralBank.UorToMeters);
                    LineStringElement lineStringElement = new LineStringElement(GeneralBank.ActiveDgnModel, null, points.ToArray());
                    RebarBase rebarBase4 = null;
                    if ( j != numX - 1)
                    {
                        rebarBase4 = new Rebar_90Degrees(this, "4", rebar4.diameter, rebar4.rebarGrade, RebarType.NoRibbed, lineStringElement.GetCurveVector(), rebar4.hookLength, rebar4.diameter * 5, 90, 90);
                    }
                    else
                    {
                        rebarBase4 = new Rebar_90Degrees(this, "4", rebar4.diameter, rebar4.rebarGrade, RebarType.NoRibbed, lineStringElement.GetCurveVector(), rebar4.hookLength, rebar4.diameter * 5, 90 + angle.Degrees, 90 + angle.Degrees);
                    }
                         
                    //if (j == numX - 1)
                    //{
                    //    DTransform3d dTransform3D = DTransform3d.FromRotationAroundLine(points[1], new DVector3d(0, 0, 1), -angle);
                    //    TransformInfo transInfo1 = new TransformInfo(dTransform3D);
                    //    lineStringElement.ApplyTransform(transInfo1);
                    //}
                    //RebarBase rebarBase4 = new RebarNoHook(this, "4", rebar4.diameter, rebar4.rebarGrade, RebarType.NoRibbed, lineStringElement.GetCurveVector());
                    rebarList.Add(rebarBase4);
                }
            }
            return rebarList;
        }

        private List<RebarBase> CreateRebarListNum5()
        {
            List<RebarBase> rebarList = new();
            var objParameter = GetUorCoverParameter();
            var rebar3 = this.GetRebarParametersOfNum3();
            var rebar5 = this.GetRebarParametersOfNum5();

            double staY = objParameter.clearSpan / 2 + objParameter.standPly - objParameter.protectiveLayer - rebar3.diameter / 1000 - rebar5.diameter / 1000 / 2;
            double staZ = objParameter.piecePly + objParameter.clearHeight + rebar3.rebarPlaceDepth - rebar3.rebarLength + rebar5.diameter / 1000 / 2;
            //单侧摆放根数
            int num = (int)(rebar5.rebarRoot / 2);

            //钢筋端点相对于原点偏移长度
            double rebarOffset = Math.Abs(staY * Math.Tan((90 - objParameter.leftLateralAngle) * Math.PI / 180));
            //钢筋距净保护层水平距离
            double horizontalLen = Math.Abs((objParameter.protectiveLayer) / Math.Cos((90 - objParameter.leftLateralAngle) * Math.PI / 180));

            
            double upStaX = 0;
            double downStaX = 0;
            if (objParameter.leftLateralAngle > 90)
            {
                upStaX = -rebarOffset + horizontalLen;
                downStaX = rebarOffset + horizontalLen;
            }
            else if (objParameter.leftLateralAngle < 90)
            {
                upStaX = rebarOffset + horizontalLen;
                downStaX = -rebarOffset + horizontalLen;
            }

            //5号钢筋长度
            double upLength = objParameter.basicsLength - objParameter.culvertGapWidth / 2 - objParameter.protectiveLayer  - upStaX;
            double downLength = objParameter.basicsLength - objParameter.culvertGapWidth / 2 - objParameter.protectiveLayer - downStaX;
            //距原点Z偏移长度
            double staOffsetZ = upStaX * objParameter.baseSlope;
            double downOffsetZ = downStaX * objParameter.baseSlope;
            //摆放起点  X轴  ：钢筋边距 + 距起点长度
            DPoint3d upStaPoint = new DPoint3d(upStaX, staY, -staZ + staOffsetZ);
            DPoint3d downStaPointR = new DPoint3d(downStaX, -staY, -staZ + downOffsetZ);
            for (int i = 0; i < num; i++)
            {
                LineElement lineElementL = GetSlopLinee(new DPoint3d(upStaPoint.X, upStaPoint.Y, upStaPoint.Z - rebar5.rebarInterval * i), upLength, objParameter.baseSlope, out DPoint3d pt1);
                RebarBase rebarBase5L = new RebarNoHook(this, "5", rebar5.diameter, rebar5.rebarGrade, RebarType.NoRibbed, lineElementL.GetCurveVector());
                rebarList.Add(rebarBase5L);

                LineElement lineElementR = GetSlopLinee(new DPoint3d(downStaPointR.X, downStaPointR.Y, downStaPointR.Z - rebar5.rebarInterval * i), downLength, objParameter.baseSlope, out DPoint3d pt2);
                RebarBase rebarBase5R = new RebarNoHook(this, "5", rebar5.diameter, rebar5.rebarGrade, RebarType.NoRibbed, lineElementR.GetCurveVector());
                rebarList.Add(rebarBase5R);
            }
            return rebarList;

        }

        private List<RebarBase> CreateRebarListNum6()
        {
            List<RebarBase> rebarList = new();
            var objParameter = GetUorCoverParameter();
            var rebar1 = this.GetRebarParametersOfNum1();
            var rebar6 = this.GetRebarParametersOfNum6();
            //钢筋端点相对于原点偏移长度
            double LeftLateralOffset = Math.Abs((objParameter.standPly  + objParameter.clearSpan / 2 + objParameter.basicsEdge - objParameter.protectiveLayer - rebar6.diameter / 1000 / 2) * Math.Tan((90 - objParameter.leftLateralAngle) * Math.PI / 180));
            //钢筋距净保护层水平距离
            double horizontalLen = Math.Abs(objParameter.protectiveLayer  / Math.Cos((90 - objParameter.leftLateralAngle) * Math.PI / 180));
            //摆放长度
            double putLength = objParameter.basicsLength - objParameter.culvertGapWidth/2 - objParameter.protectiveLayer - rebar6.diameter / 1000 - LeftLateralOffset - horizontalLen;
            //摆放间距
            double putDistance = 1.0 / (rebar6.rebarRoot - 1);
            //摆放根数
            int root = (int)Math.Floor(putLength / putDistance) + 1;

            double staX = objParameter.basicsLength - objParameter.culvertGapWidth / 2 - objParameter.protectiveLayer - rebar6.diameter / 1000 / 2;
            double staY = objParameter.clearSpan / 2 + objParameter.standPly + objParameter.basicsEdge - objParameter.protectiveLayer - rebar6.diameter / 1000 / 2;
            double staZ = objParameter.piecePly + objParameter.clearHeight + objParameter.protectiveLayer + rebar1.diameter / 1000 + rebar6.diameter / 1000 / 2;
            for (int i = 0; i < root; i++)
            {
                //距原点Z偏移长度
                double offsetZ = (staX - putDistance * i) * objParameter.baseSlope;
                LineElement lineElement = new LineElement(GeneralBank.ActiveDgnModel, null, new DSegment3d(
                    new DPoint3d(staX - putDistance * i, staY, -(staZ + -offsetZ)) * GeneralBank.UorToMeters,
                    new DPoint3d(staX - putDistance * i, -staY, -(staZ + -offsetZ)) * GeneralBank.UorToMeters));
                RebarBase rebarBase2 = new RebarNoHook(this, "6", rebar6.diameter, rebar6.rebarGrade, RebarType.NoRibbed, lineElement.GetCurveVector());
                rebarList.Add(rebarBase2);
            }
            return rebarList;
        }

        /// <summary>
        /// 获取1#钢筋构造参数
        /// </summary>
        /// <returns>边距,钢筋根数,等级,直径</returns>
        private (double edgeDistance, int rebarRoot, string rebarGrade, double diameter) GetRebarParametersOfNum1()
        {
            var dgvOfRebar = this.rebarEntity.dgv_Rebar1;
            var edgeDistance = Convert.ToDouble(dgvOfRebar[0]) / 100;
            var rebarRoot = Convert.ToInt16(dgvOfRebar[1]);
            var rebarGrade = Convert.ToString(dgvOfRebar[2]);
            var diameter = Convert.ToDouble(dgvOfRebar[3]);
            return (edgeDistance, rebarRoot, rebarGrade, diameter);
        }
        /// <summary>
        /// 获取2#钢筋构造参数
        /// </summary>
        /// <returns>边距,钢筋每延米根数,直径,等级,弯钩长度</returns>
        private (double edgeDistance, int rebarRoot, double diameter, string rebarGrade, double hookLength) GetRebarParametersOfNum2()
        {
            var dgvOfRebar = this.rebarEntity.dgv_Rebar2;
            var edgeDistance = Convert.ToDouble(dgvOfRebar[0]) / 100;
            var rebarRoot = Convert.ToInt16(dgvOfRebar[1]);
            var diameter = Convert.ToDouble(dgvOfRebar[2]);
            var rebarGrade = Convert.ToString(dgvOfRebar[3]);
            var hookLength = Convert.ToDouble(dgvOfRebar[4]);
            return (edgeDistance, rebarRoot, diameter, rebarGrade, hookLength);
        }

        /// <summary>
        /// 获取2'钢筋构造参数
        /// </summary>
        /// <returns>边距,根数(单侧),钢筋直径,钢筋等级</returns>
        private (double edgeDistance, int rebarRoot, double diameter, string rebarGrade, double hookLength) GetRebarParametersOfNum2_1()
        {
            var dgvOfRebar = this.rebarEntity.dgv_Rebar2_1;
            var edgeDistance = Convert.ToDouble(dgvOfRebar[0]) /100;
            var rebarRoot = Convert.ToInt16(dgvOfRebar[1]);
            var diameter = Convert.ToDouble(dgvOfRebar[2]);
            var rebarGrade = Convert.ToString(dgvOfRebar[3]);
            var hookLength = Convert.ToDouble(dgvOfRebar[4]);
            return (edgeDistance, rebarRoot, diameter, rebarGrade, hookLength);
        }

        /// <summary>
        /// 获取3#钢筋构造参数
        /// </summary>
        /// <returns>插入基础深度,钢筋每延米根数(双侧),钢筋等级,钢筋总长</returns>
        private (double rebarPlaceDepth, int rebarRoot, string rebarGrade, double diameter, double rebarLength) GetRebarParametersOfNum3()
        {
            var dgvOfRebar = this.rebarEntity.dgv_Rebar3;
            var rebarPlaceDepth = Convert.ToDouble(dgvOfRebar[0]) / 100;
            var rebarRoot = Convert.ToInt16(dgvOfRebar[1]);
            var rebarGrade = Convert.ToString(dgvOfRebar[2]);
            var diameter = Convert.ToDouble(dgvOfRebar[3]);
            var rebarLength = Convert.ToDouble(dgvOfRebar[4]) / 100;
            return (rebarPlaceDepth, rebarRoot, rebarGrade, diameter, rebarLength);
        }

        /// <summary>
        /// 获取4#钢筋构造参数
        /// </summary>
        /// <returns>水平间距,垂直间距,钢筋等级,钢筋直径,弯钩长度</returns>
        private (double distanceX, double distanceY, string rebarGrade, double diameter, double hookLength) GetRebarParametersOfNum4()
        {
            var dgvOfRebar = this.rebarEntity.dgv_Rebar4;
            string[] edges = dgvOfRebar[0].ToString().Split('x');
            var distanceX = Convert.ToDouble(edges[0]) / 100;
            var distanceY = Convert.ToDouble(edges[1]) / 100;
            var rebarGrade = Convert.ToString(dgvOfRebar[1]);
            var diameter = Convert.ToDouble(dgvOfRebar[2]);
            var hookLength = Convert.ToDouble(dgvOfRebar[3]);
            return (distanceX, distanceY, rebarGrade, diameter, hookLength);
        }

        /// <summary>
        /// 获取5#钢筋构造参数
        /// </summary>
        /// <returns>同侧间距,钢筋等级,钢筋直径,钢筋个数</returns>
        private (double rebarInterval, string rebarGrade, double diameter, int rebarRoot) GetRebarParametersOfNum5()
        {
            var dgvOfRebar = this.rebarEntity.dgv_Rebar5;
            var rebarInterval = Convert.ToDouble(dgvOfRebar[0]) / 100;
            var rebarGrade = Convert.ToString(dgvOfRebar[1]);
            var diameter = Convert.ToDouble(dgvOfRebar[2]);
            var rebarRoot = Convert.ToInt16(dgvOfRebar[3]);
            return (rebarInterval, rebarGrade, diameter, rebarRoot);
        }

        /// <summary>
        /// 获取6#钢筋构造参数
        /// </summary>
        /// <returns>同侧间距,钢筋等级,钢筋直径,钢筋个数</returns>
        private (double edgeDistance, string rebarGrade, int rebarRoot, double diameter) GetRebarParametersOfNum6()
        {
            var dgvOfRebar = this.rebarEntity.dgv_Rebar6;
            var rebarInterval = Convert.ToDouble(dgvOfRebar[0]);
            var rebarGrade = Convert.ToString(dgvOfRebar[1]);
            var rebarRoot = Convert.ToInt16(dgvOfRebar[2]);
            var diameter = Convert.ToDouble(dgvOfRebar[3]);
            return (rebarInterval, rebarGrade, rebarRoot, diameter);
        }


        private void RotateElement(DPoint3d dPoint3D,double angle)
        {
            //DTransform3d trans = DTransform3d.Identity;
            //DVector3d dVector3D = new DVector3d(0, 0, 1);
            //DMatrix3d matrix = DMatrix3d.Rotation(dVector3D, rotationAngle);
            ////DTransform3d trans1 = DTransform3d.FromMatrixAndFixedPoint(matrix, origin);
        }
 
        public SolidKernelEntity CreateBodyFromSweep(CurveVector pathCur, CurveVector secCur, DgnModel modelRef)
        {
            pathCur.GetStartEnd(out DPoint3d startPt, out _, out DVector3d startTangent, out _);
            CurveVector secCur1 = secCur.Clone();
            BCIMNETGS.SolidUtil.Create.BodyFromSweep(out SolidKernelEntity entity, secCur1, pathCur, modelRef, false, true, false, null, null, null, null);
            return entity;
        }



        public static SolidKernelEntity CreateBodyFromExtrusion(CurveVector secCur, double extrusionLength, DPoint3d centroid, DVector3d extrudDir, DgnModel modelRef)
        {
            BentleyStatus status = CIMNETSolid.SolidUtil.Create.BodyFromExtrusion(
                out SolidKernelEntity entity, secCur, extrusionLength, modelRef, extrudDir, false, null);
            return entity;
        }

        public override void CreateElementECProperty(Element element, List<Tuple<string, CustomProperty.TypeKind, bool, bool>> tuples)
        {
            throw new NotImplementedException();
        }

        public override void SetECInstanceValue(IDgnECInstance dgnECInstance, List<(string propertyName, string calculationBasis, string computationalFormula)> propertyData)
        {
            throw new NotImplementedException();
        }

        public override List<(string standardName, string standValue)> CreateStandardECProperty()
        {
            throw new NotImplementedException();
        }

        public override void SaveStandardECProperty(IDgnECInstance dgnECInstance)
        {
            var retJObject = new JObject();
            foreach (var item in this.CreateStandardECProperty())
            {
                retJObject[item.standardName] = item.standValue;
            }

            // 属性赋值
            IEnumerable<IECProperty> eCProperties = dgnECInstance.ClassDefinition.Properties(true);
            foreach (IECProperty eCProperty in eCProperties)
            {
                if (eCProperty.DisplayLabel.Equals("CoverHiddenData"))
                {
                    IECPropertyValue eCPropertyValue =
                        dgnECInstance.FindPropertyValue(eCProperty.Name, false, false, false, false);
                    if (eCPropertyValue != null)
                    {
                        var saveStr = retJObject.ToString(Newtonsoft.Json.Formatting.None);
                        dgnECInstance.SetValue<string>(eCProperty.Name, saveStr);
                    }
                }
            }

            dgnECInstance.ScheduleChanges(dgnECInstance.Element);
            dgnECInstance.Element.ReplaceInModel(dgnECInstance.Element);
        }

        public override double GetVolumeOfElement(Element element)
        {
            double ret = 0.0;
            var instCol = DgnECManager.Manager.GetElementProperties(element, ECQueryProcessFlags.SearchAllClasses);
            foreach (var inst in instCol)
            {
                IEnumerator<IECProperty> propertyEnum = inst.ClassDefinition.GetEnumerator();
                while (propertyEnum.MoveNext())
                {
                    if (propertyEnum.Current.Name == "Volume")
                    {
                        IECPropertyValue propertyValue = inst.GetPropertyValue(propertyEnum.Current.Name);
                        ret = propertyValue.DoubleValue / Math.Pow(GeneralHelpers.UorToMeters, 3);
                        break;
                    }
                }
            }
            return ret;
        }
    }
}
